﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Majoopic.Utility.Properties;

namespace Majoopic.Utility.Image
{
    /// <summary>
    /// Represent the rational type in a EXIF information.
    /// Rational is a long with the first 4 byte = the numerator and the last 4 byte = denominator
    /// </summary>
    public class Rational
    {
        /// <summary>
        /// Numerator
        /// </summary>
        public int Numerator
        {
            get;
            set;
        }

        /// <summary>
        /// Denominator
        /// </summary>
        public int Denominator
        {
            get;
            set;
        }


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="value"></param>
        public Rational(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value cannot be null");
            }
            if (value is ulong == false)
            {
                throw new ArgumentException("value must be ulong type");
            }
            byte[] valueBytes = BitConverter.GetBytes((ulong)value);
            this.Numerator = BitConverter.ToInt32(valueBytes, 0);
            this.Denominator = BitConverter.ToInt32(valueBytes, 4);
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="numerator"></param>
        /// <param name="denominator"></param>
        public Rational(int numerator, int denominator)
        {
            this.Numerator = numerator;
            this.Denominator = denominator;
        }

        /// <summary>
        /// Return the double value 
        /// </summary>
        /// <returns></returns>
        public double ToDouble()
        {
            if (this.Denominator == 0)
            {
                return 0;
            }
            return (double)this.Numerator / (double)this.Denominator;
        }

        public override string ToString()
        {
            double currentValue = this.ToDouble();
            if (currentValue == 0)
            {
                return "0";
            }
            if (currentValue > 1)
            {
                return string.Format("{0:0.##}", currentValue);
            }

            return string.Format("1/{0:0}", (double)1 / currentValue);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            Rational rationalObj = obj as Rational;
            if (rationalObj != null)
            {
                return rationalObj.ToDouble() == this.ToDouble();
            }
            return false;
        }
    }
}
